/**
 * @Author       : oak-c
 * @Date         : 2021-01-19 12:29:30
 * @Description  : 系统参数
 * @LastEditors  : oak-c
 * @LastEditTime : 2021-01-22 14:22:47
 * @FilePath     : /src/service/global/config.service.ts
 */
import { GlobalConfigRepo } from '@/entities'
import { IBodyUser, ICompany, ICTU, IPagesOption } from '@/interface'
import { CoreException, CoreExceptionType } from '@/modules'
import { timestampFormat } from '@/util'
import { Injectable, OnModuleInit } from '@nestjs/common'
import { ConfigService } from '@donews/nestjs-config'

interface IGConfig extends ICTU {
    key?: string
    value?: any
    note?: string
    affiliationid?: string
    affiliationType?: number
    company?: ICompany
}

const defaultConfig = [{ key: 'VERSION_PREFIX', value: '3.1', note: '大版本' }]

@Injectable()
export class GlobalConfigService implements OnModuleInit {
    constructor(private readonly globalConfigRepo: GlobalConfigRepo, private readonly config: ConfigService) {}

    public async onModuleInit() {
        for await (const c of defaultConfig) {
            const exiting = await this.globalConfigRepo.findOne({
                key: c.key,
                affiliationid: '0000',
                affiliationType: 0,
            })
            const ut = timestampFormat()
            if (!exiting) {
                await this.globalConfigRepo.save(
                    this.globalConfigRepo.create({
                        ...c,
                        affiliationid: '0000',
                        affiliationType: 0,
                        au: 'system',
                        ct: ut,
                    }),
                )
            } else {
                await this.globalConfigRepo.save({
                    ...exiting,
                    ...c,
                    ut,
                    ed: 'system',
                })
            }
        }
    }

    /**
     * 更新配置
     * @param option
     */
    public async setConfig(option: IGConfig & IBodyUser) {
        const { key, value, note, affiliationid, affiliationType } = option
        if (!affiliationid) {
            throw new CoreException(CoreExceptionType.ERROR_CORE_CONFIG_AFFILIATION_FAIL)
        }
        const ed = option.__user.name
        const ut = timestampFormat()
        const exiting = await this.globalConfigRepo.findOne({ key, affiliationid, affiliationType })
        if (exiting) {
            await this.globalConfigRepo.update(exiting.id, { value, note, ed, ut })
        } else {
            await this.globalConfigRepo.save(
                this.globalConfigRepo.create({
                    key,
                    value,
                    note,
                    // affiliationid,
                    // affiliationType,
                    ct: ut,
                    au: ed,
                }),
            )
        }
        return {}
    }

    /**
     * @description: 获取单个参数
     * @param {string} key
     * @param projectid
     * @param companyid
     * @return {*}
     */
    public async getConfig(key: string, projectid?: string, companyid?: string) {
        const affiliationid = projectid || companyid || '0000'
        const affiliationType = companyid || affiliationid === '0000' ? 0 : 1
        let config = await this.globalConfigRepo.findOne({
            key,
            affiliationid,
            affiliationType,
        })
        if (!config) {
            config = await this.globalConfigRepo.findOne({
                key,
                affiliationid: '0000',
                affiliationType: 0,
            })
            if (config) {
                await this.globalConfigRepo.save(
                    this.globalConfigRepo.create({
                        key,
                        affiliationid,
                        affiliationType,
                        note: config.note,
                        value: config.value,
                        au: 'system',
                        ct: timestampFormat(),
                    }),
                )
            }
        }
        if (!config) {
            throw new CoreException(CoreExceptionType.ERROR_CORE_CONFIG_IS_MISSING)
        }
        return isNaN(Number(config.value)) ? config.value : Number(config.value)
    }

    /**
     * @description: 批量获取参数
     * @param {string} keys
     * @param projectid
     * @param {string} companyid
     * @return {*}
     */
    public async getConfigs(keys: string[], projectid?: string, companyid?: string) {
        const result: any[] = []
        for await (const k of keys) {
            result.push(await this.getConfig(k, projectid, companyid))
        }
        return result
    }

    // /**
    //  * 查询企业参数配置
    //  * @param option
    //  */
    // public async queryCompanyConfig(option: IGConfig & IBodyUser & IPagesOption) {
    //     const { key, note, current = 1, pageSize = 50 } = option
    //     const companyid = option.__user.companyid
    //     const configBuilder = this.globalConfigRepo
    //         .createQueryBuilder('c')
    //         .leftJoinAndMapOne('c.company', 'company', 'cc', 'cc.companyid=c.affiliationid')
    //         .where('c.affiliationid=:companyid', { companyid })
    //         .andWhere('c.affiliationType=0')
    //     key && configBuilder.andWhere('c.key like :key', { key: `%${key.toUpperCase()}%` })
    //     note && configBuilder.andWhere('c.note like :note', { note: `%${note}%` })
    //     const [data, total] = await configBuilder
    //         .skip((current - 1) * pageSize)
    //         .take(pageSize)
    //         .getManyAndCount()
    //     return {
    //         data,
    //         total,
    //         current,
    //         pageSize,
    //         count: data.length,
    //     }
    // }

    /**
     * 删除配置
     * @param id
     */
    public async deleteConfig(id: number) {
        const exiting = await this.globalConfigRepo.findOne(id)
        if (exiting) {
            if (exiting.affiliationid === '0000') {
                throw new CoreException(CoreExceptionType.ERROR_CORE_CONFIG_ADMIN_DELETE)
            }
            await this.globalConfigRepo.delete(id)
        }
        return {}
    }

    public async queryVersion() {
        return this.config.get('client', {})
    }
}
